﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace PersonaLibrary.Search
{
    public class DateSearchProperty : BaseSearchProperty
    {
        public DateSearchProperty(ParameterExpression parametr)
            :base(parametr)
        {
        }

        protected override List<string> CreateUnaryOperators()
        {
            return new List<string>
                       {
                           "День",
                           "Месяц",
                           "Год",
                           "Возраст"
                       };
        }

        public override Expression CreateUnary()
        {
            Expression result = null;

            switch (SelectedUnaryOperator)
            {
                case "День":
                    result = Property.NotNullTesting(Day());
                    break;
                case "Месяц":
                    result = Property.NotNullTesting(Month());
                    break;
                case "Год":
                    result = Property.NotNullTesting(Year());
                    break;
                case "Возраст":
                    result = Property.NotNullTesting(Age());
                    break;
            }
            return result;
        }

        private Expression Day()
        {
            var tmpProperty = Expression.Property(Expression.Property(Property, "Value"), "Day");
            return Expression.Equal(tmpProperty, Expression.Call(typeof(Int32).GetMethod("Parse", new []{typeof(string)}), Constant));
        }

        private Expression Month()
        {
            Expression tmpExpression = Expression.Call(Expression.Property(Property, "Value"), typeof(DateTime).GetMethod("ToString", new[] { typeof(string), typeof(IFormatProvider) }),
                Expression.Constant("MMMM"), Expression.Constant(new CultureInfo("ru-ru")));
            return Expression.Call(typeof(string).GetMethod("Equals", new Type[]{typeof(string), typeof(string), typeof(StringComparison)}), 
                tmpExpression, Constant, Expression.Constant(StringComparison.OrdinalIgnoreCase));
        }

        private Expression Year()
        {
            var tmpProperty = Expression.Property(Expression.Property(Property, "Value"), "Year");
            return Expression.Equal(tmpProperty, Expression.Call(typeof(Int32).GetMethod("Parse", new [] { typeof(string) }), Constant));
        }

        private Expression Age()
        {
            var dateNow = Expression.Constant(DateTime.Now.Year);
            var tmpProperty = Expression.Property(Expression.Property(Property, "Value"), "Year");
            return Expression.Equal(Expression.Call(typeof(DateSearchProperty).GetMethod("minus", new [] { typeof(Int32), typeof(Int32) }), dateNow, tmpProperty), Expression.Call(typeof(Int32).GetMethod("Parse", new Type[] { typeof(string) }), Constant));
        }

        public static int Minus(int i, int y)
        {
            return i - y;
        }
    }
}
